W dokumencie tym zajmę się opisem dokonanej eksploracji danych dotyczących pożarów lasów rejonów Portugalii. Pokażę kilka zależności pomiędzy zmiennymi zawartymi w ramce danych oraz sformułuję idące w analizy wnioski. Używane dane zawierają informację dotyczące newralgicznych zmiennych sprzyjających, bądź niesprzyjających występowaniu pożarów w rejonach leśnych.
Użyta ramka danych : https://www.apispreadsheets.com/datasets/129
# Przygotowanie bibliotek
import pandas as pd
import seaborn as sns
from matplotlib import pyplot as plt
from pandas_profiling import ProfileReport
# Wgranie ramek danych
df = pd.read_csv('forest_fires_dataset.csv')
DESCR = pd.read_csv('attributes_forest_fires.csv')
Poniżej znajduje się opis kolumn oraz ich typ, które znajdują się w naszej ramce danych. Z informacji źródłowych poadanych na stronie udostępniającej dane, wiemy, iż cała nasza ramka danych nie zawiera ani wartości null, ani NaN. Co więcej wszystkie wartości są wypełnione poprawnie poprzez typ im przypisany. Oznacza to iż nie ma potrzeby dokonywać "czyszczenia danych", zatem taki zabieg nie jest potrzebny, więc został on pominięty w tym dokumencie. Nie zmienia to jednak faktu, iż dokonałem modyfikacji w ramce pod względem typów zmiennych. W dwóch przypadkach, gdzie dane były właśnie tego typu, postarałem się odzwierciedlić je w numerycznym typie.
print(DESCR)
Ramka prezentuje się w sposób następujący
print(df.head())
## Ilość wierszy oraz kolumn
print("\nIlość odpowiednio wierszy oraz kolumn wynosi:", df.shape)
Zobaczmy, czy naprawdę nie brakuje żadnych wartości, jak upewnili nas autorzy ramki.
df.info()
Nie zostaliśmy okłamani.
Przyjżyjmy się najpierw podstawowym statystykom poszczególnych zmiennych. Ponieważ większość z nich (11 z 13) jest typu float, otrzymamy otrzymaną tabele danych za pomocą instancji ".describe()"
print(df.describe())
Najbardziej "interesujące" powinny wydawać się nam te zmienne, które są najbardziej opisywalne, tudzież takie, których odchylenie standardowe jest dość niewielkie. W ogólności odchylenie standardowe jest dość niewielkie dla większości danych, lecz dla np. DMC, DC ich wartości są wyjątkowo spore (szczgólnie dla DM).
#Wizualizacja powyższych wyników w postaci histogramów
df.hist(bins = 80,figsize = (20,18))
plt.show()
Jak widzimy rozkład zmiennych temperatury, watru, ISI, oraz współczynnikowi RH są dośc podobne do rozkładu normalnego, co jest dużym indykatorem, iż zmienne te będą dość użyteczne w naszej analizie zależności danych zmiennych.
W przypadku innych zmiennych dystrybucje są inne, lecz to nie zawsze implikuje negatywność takiej cechy. Zmienne dla deszczu oraz pola powierzchni są niemal scentrowane na jednej wartości, co mówi nam jednoznacznie o warunkach sprzyjających występowania pożarów.
Dla zmiennej DMC, dane są bardziej rozproszone, lecz formują pewien dość spłaszczony wykres rozkładu normalnego, będzie ciężej z ekstrakcją wniosków z tej zmiennej, lecz na pewno pomoże ona nam przy analizie.
Dla współrzędnych, ich wartości nie są zbyt zróżnicowane oraz są dość stale rozdzielone (przynajmniej dla zmiennej X), więc raczej dla uproszczenia analizy uznam iż nie wniosą wystarczająco dużo informacji do niej.
Zobaczę na początku jak graficznie zmienne mają się do siebie, czy są jakieś interesujące zależności, które na "oko" można uznać za wystarczające do stwierdzenia jakiś zależności między zmiennymi. Ich graficzna reprezentacja będzie użyteczna dla wybierania przez jednostkę ludzką ciekawych zależności, a przy okazji wygląda dość estetycznie.
sns.pairplot(df)
Teraz zerknijmy dokładniej na poszczególne wykresy korelacji, lecz tylko na te ukazujące pewne zależności. Postaram się wnieść odpowiedzieć logikę stojącą za tą relacją, oraz wnieść kilka słów mojej opinii.
sns.pairplot(df, y_vars="FFMC", x_vars=df.columns.values[3:9])
Indeks FFMC jest powiązany pewną "lekką krzywą" z zmiennymi DMC, DC, ISI. W przypadku temperatury zaobserwować da się już liniową zależność. Więc ostatecznie najwięcej informacji otrzymamy z zależności temperatury oraz FFMC.
sns.pairplot(df, y_vars="DMC", x_vars=df.columns.values[1:4])
sns.pairplot(df, y_vars="DMC", x_vars=df.columns.values[4:8])
Ponieważ jak już wiemy dystrybucja współczynnika DMC nie była idealnym rozkładem normalnym, to jego realacje z niektórymi zmiennymi nie jest aż tak klarowna, lecz jak widzimy z powyższych wykresów istnieje. W szcególnyści widać kilka grup w zależności DMC orac DC, które satysfakcjonują zależność liniową. Jest to idealna zależność gdyż nie tylko dowiadujemy się o ich liniowości, ale również o potencjalnej analizie ze względu na grupy i znalezieniu jej, idealne zadanie dla machine-learningu.
Przy zależności FFMC oraz ISI, obserwujemy zbieżność zleżności do pewnej wartości i ich scentrowanie, co prawdopodobnie nie dałoby nam precyzyjnej zależności.
sns.pairplot(df, y_vars="temp", x_vars=df.columns.values[4:8])
sns.pairplot(df, y_vars="temp", x_vars=df.columns.values[8:12])
W przypadku przyjżenia się bliżej zmiennej temperatury, jej najbardziej klarowną zależnością jest ta z współczynnikiem RH. Reszta wydaje się mieć niezbyt duży współczynnik korelacji. Jednak, dla przykładu, wykres dla temperatury oraz DC oraz (w mniejszym stopniu lecz nadal) dla temperatury oraz DMC, wskazuje nam pewne dwie potencjalne grupy, gdyż wartości układają się do dwóch zbiorów.
sns.countplot(x="month", data=df, color ="lightblue",order=["jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"])
Patrząc na wyniki poprzednie można było zobaczyć na pewne dysproporcje w rozkładzie miesięcy, a więc dokonałem ich przeliczenia (raport ich uwzględnił przez ich typ danych kategorycznych, a nie numerycznych). Widać klarownie, iż sierpień i wrzesień są miesiącami "pożarowymi".
Jeżeli dysponujemy liczną ilością zmiennych to wygodnym rozwiązaniem może być użycie tabeli korelacji by znaleść analitycznie zależności, a następnie przedstawić je graficznie.
Jak widzimy, wcześniej omawiane przeze mnie wartości mają dość znaczące wartości korelacji (przynajmniej większe niż 0.2), od razu widzimy, które zmienne można od razu odrzucić z naszej analizy.
Korelacja = df.drop(columns = ["month","day"])
Korelacja = Korelacja.corr()
sns.heatmap(Korelacja,annot = False)
plt.show()
# Przygotowanie raportu z pakietu pandas_profiling
ProfileReport(df,title = "Raport")
Narzędzie jest z cała pewnością niezwykle wygodne do szybkiego przygotowania szybkiej i dość obszernej analizy dotyczącego danego zagadnienia. Raport zaspokoił najbardziej główne zapytania oraz informacje, dotyczące naszych danych. Narzędzie oszczędziłoby nam dużą ilość czasu, lecz nie jest również idealne.
Wedle mojej opinii, analiza dokonana przez program jest jak najbardziej obszerna, czasami (przez jej schematyczność) prezentuje niepotrzebne zależności, lub całkowity ich brak. Niektóre części analizy są po prostu redundantne, i choć wychodzę z założenia iż przedstawienie większej ilości (nawet mało istotnych danych) jest lepsze niż podjęcie ryzyka pominięcia ważnej zależności, to program mogłby uwzględniać "zwięzły" raport, uwzględniający, wedle kryterium, tylko istotne wyniki.
Co więcej powyższa analiza jest jak najbardziej pomocna, lecz nie modyfikuje zbytnio ramki danych, na której operujemy. Przyjmuje otrzymane dane i wykonuje swoją pracę, nie dokonując na przykład zamiany danych kategorycznych na numeracyjne, bądź wypełnienie wartości NULL, bądź "NaN", wedle matematycznego wzorca postępowania. Również nie dokonuje "modyfikacji" na ramce danych (nie dzieli ich, nie usuwa wartości skrajnych, nie dokonuje dogłębszej analizy), zatem jest dość powierzchowna. Najlepiej narzędzia użyć na już spreparowanej ramce danych.